-- 
-- Please see the readme.txt file included with this distribution for 
-- attribution and copyright information.
--

function getClosestSnapPoint(x, y)
	if hasGrid() then
		local type = getGridType();
		if type == "hex" then
			local qw, hh = getGridHexElementDimensions();
			local ox, oy = getGridOffset();

			-- The hex grid separates into a non-square grid of elements sized qw*hh, the location in which dictates corner points
			if type == "hexcolumn" then
				local col = math.floor((x - ox) / qw);
				local row = math.floor((y - oy) * 2 / size);

				local evencol = col % 2 == 0;
				local evenrow = row % 2 == 0;

				local lx = (x - ox) % qw;
				local ly = (y - oy) % hh;

				if (evenrow and evencol) or (not evenrow and not evencol) then
					-- snap to lower right and upper left
					if lx + ly * (qw/hh) < qw then
						return ox + col*qw, oy + math.floor(row*size/2);
					else
						return ox + (col+1)*qw, oy + math.floor((row+1)*size/2);
					end
				else
					-- snap to lower left and upper right
					if (qw-lx) + ly * (qw/hh) < qw then
						return ox + (col+1)*qw, oy + math.floor(row*size/2);
					else
						return ox + col*qw, oy + math.floor((row+1)*size/2);
					end
				end
			else -- "hexrow"
				local col = math.floor((x - ox) * 2 / size);
				local row = math.floor((y - oy) / qw);

				local evencol = col % 2 == 0;
				local evenrow = row % 2 == 0;

				local lx = (x - ox) % hh;
				local ly = (y - oy) % qw;

				if (evenrow and evencol) or (not evenrow and not evencol) then
					-- snap to lower right and upper left
					if lx * (qw/hh) + ly < qw then
						return ox + math.floor(col*size/2), oy + row*qw;
					else
						return ox + math.floor((col+1)*size/2), oy + (row+1)*qw;
					end
				else
					-- snap to lower left and upper right
					if (hh-lx) * (qw/hh) + ly < qw then
						return ox + math.floor((col+1)*size/2), oy + row*qw;
					else
						return ox + math.floor(col*size/2), oy + (row+1)*qw;
					end
				end
			end

		else --if type == "square" then
			local size = getGridSize();
			local ox, oy = getGridOffset();

			local centerx = math.floor((x - ox)/size)*size + size/2 + ox + 1;
			local centery = math.floor((y - oy)/size)*size + size/2 + oy + 1;

			local centerxdist = x - centerx;
			local centerydist = y - centery;

			local cornerx = math.floor((x - ox + size/2)/size)*size + ox + 1;
			local cornery = math.floor((y - oy + size/2)/size)*size + oy + 1;

			local cornerxdist = x - cornerx;
			local cornerydist = y - cornery;

			local cornerlimit = size / 4;

			if (math.abs(cornerxdist) <= cornerlimit) and (math.abs(cornerydist) <= cornerlimit) and 
			   		((centerxdist*centerxdist+centerydist*centerydist) > (cornerxdist*cornerxdist+cornerydist*cornerydist)) then
				return cornerx, cornery;
			else
				if math.abs(cornerxdist) <= cornerlimit then
					return cornerx, centery;
				end
				if math.abs(cornerydist) <= cornerlimit then
					return centerx, cornery;
				end
				return centerx, centery;
			end

		end
	end
	
	return x, y;
end

function onTokenSnap(token, x, y)
	if hasGrid() then
		return getClosestSnapPoint(x, y);
	else
		return x, y;
	end
end

function onPointerSnap(startx, starty, endx, endy, type)
	local newstartx = startx;
	local newstarty = starty;
	local newendx = endx;
	local newendy = endy;

	if hasGrid() then
		newstartx, newstarty = getClosestSnapPoint(startx, starty);
		newendx, newendy = getClosestSnapPoint(endx, endy);
	end

	return newstartx, newstarty, newendx, newendy;
end

function onMeasureVector(token, vector)
	if hasGrid() then
		local type = getGridType();
		if type == "hex" then
			local pixels = 0;

			for i = 1, #vector do
				pixels = pixels + math.floor(math.sqrt(vector[i].x*vector[i].x + vector[i].y*vector[i].y));
			end
			
			local units = math.floor(pixels / getGridSize());
			return "" .. units;
		else -- if type == "square" then
			local diagonals = 0;
			local straights = 0;
			local gridsize = getGridSize();

			for i = 1, #vector do
				local gx = math.abs(math.floor(vector[i].x / gridsize));
				local gy = math.abs(math.floor(vector[i].y / gridsize));

				if gx > gy then
					diagonals = diagonals + gy;
					straights = straights + gx - gy;
				else
					diagonals = diagonals + gx;
					straights = straights + gy - gx;
				end
			end

			local squares = diagonals + straights;
			return "" .. squares;

		end
	end
	
	return "";
end

function onMeasurePointer(length)
	if hasGrid() then
		return "" .. math.floor(length / getGridSize());
	end
	
	return "";
end

function onGridStateChanged(type)
	if User.isHost() then
		if type == "hex" then
			setTokenOrientationCount(12);
		else
			setTokenOrientationCount(8);
		end
	end
end

function onInit()
	onGridStateChanged(getGridType());
end